/*
 * JVM_OpcodeLoad.c
 *
 *  Created on: 03.01.2011
 *      Author: Tavin
 */

#include "JVM_Opcode.h"
#include "JVM_OpcodeLoad.h"
#include "JVM_DataTypes.h"
#include "JVM_StatusCodes.h"
#include "JVM_CP_Table.h"
#include "JVM_CP_Integer.h"
#include "JVM_CP_Float.h"

#include "JVM_ClassTable.h"

/****************************************************************************************/
/*																						*/
/*	Function : JV_cmd_bipush								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JV_cmd_bipush()
{
	int8_t byteValue;
	int32_t intValue;

	byteValue=JVM_Opcode_getCodeByte();

	intValue=byteValue;


	JVM_Opcode_pushIntValue(intValue);

	return(STCD_OK);
}
/****************************************************************************************/
/*																						*/
/*	Function : JV_cmd_sipush								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JV_cmd_sipush()
{

	int16_t shortValue;
	int32_t intValue;

	shortValue=JVM_Opcode_getCodeShort();

	intValue=shortValue;

	JVM_Opcode_pushIntValue(intValue);

	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_aconst_null							Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.15			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_aconst_null()
{

	JVM_StackFrame_t * myStackFrame;

	myStackFrame=JVM_Opcode_getActiveStackFrame();
	JVM_Opcode_pushReference(HANDLE_NULL);

	return(STCD_OK);
}


/****************************************************************************************/
/*																						*/
/*	Function : JVM_wcmd_aload								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.6			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_wcmd_aload()
{
	JVM_HandleNumber_t reference;
	uint16_t index;

	index=JVM_Opcode_getCodeShort();


	reference=JVM_Opcode_getReferenceVar(index);
	JVM_Opcode_pushReference(reference);

	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_aload								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.6			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_aload()
{
	JVM_HandleNumber_t reference;
	uint8_t index;

	index=JVM_Opcode_getCodeByte();

	reference=JVM_Opcode_getReferenceVar(index);
	JVM_Opcode_pushReference(reference);

	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_aload_0								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.6			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_aload_0()
{
	JVM_HandleNumber_t reference;

	reference=JVM_Opcode_getReferenceVar(0);
	JVM_Opcode_pushReference(reference);

	return(STCD_OK);
}
/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_aload_1								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.6			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_aload_1()
{
	JVM_HandleNumber_t reference;

	reference=JVM_Opcode_getReferenceVar(1);
	JVM_Opcode_pushReference(reference);

	return(STCD_OK);
}
/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_aload_2								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.6			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_aload_2()
{
	JVM_HandleNumber_t reference;

	reference=JVM_Opcode_getReferenceVar(2);
	JVM_Opcode_pushReference(reference);

	return(STCD_OK);
}
/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_aload_3								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.6			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_aload_3()
{
	JVM_HandleNumber_t reference;

	reference=JVM_Opcode_getReferenceVar(3);
	JVM_Opcode_pushReference(reference);

	return(STCD_OK);
}
/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_iload								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.4			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_iload()
{
	uint32_t tmpValue;
	uint8_t index;

	index=JVM_Opcode_getCodeByte();

	tmpValue=JVM_Opcode_getIntVar(index);
	JVM_Opcode_pushIntValue(tmpValue);

	return(STCD_OK);
}


/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_iload_0								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.4			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_iload_0()
{
	uint32_t tmpValue;

	tmpValue=JVM_Opcode_getIntVar(0);
	JVM_Opcode_pushIntValue(tmpValue);

	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_iload_1								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.4			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_iload_1()
{
	uint32_t tmpValue;

	tmpValue=JVM_Opcode_getIntVar(1);
	JVM_Opcode_pushIntValue(tmpValue);

	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_iload_2								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.4			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_iload_2()
{
	uint32_t tmpValue;

	tmpValue=JVM_Opcode_getIntVar(2);
	JVM_Opcode_pushIntValue(tmpValue);

	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_iload_3								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.4			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_iload_3()
{
	uint32_t tmpValue;

	tmpValue=JVM_Opcode_getIntVar(3);
	JVM_Opcode_pushIntValue(tmpValue);

	return(STCD_OK);
}





/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_lload								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.4			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_lload()
{
	uint64_t tmpValue;
	uint8_t index;

	index=JVM_Opcode_getCodeByte();

	tmpValue=JVM_Opcode_getLongVar(index);
	JVM_Opcode_pushLongValue(tmpValue);

	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_lload_0								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.4			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_lload_0()
{
	uint64_t tmpValue;

	tmpValue=JVM_Opcode_getLongVar(0);
	JVM_Opcode_pushLongValue(tmpValue);

	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_lload_1								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.4			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_lload_1()
{
	uint64_t tmpValue;

	tmpValue=JVM_Opcode_getLongVar(1);
	JVM_Opcode_pushLongValue(tmpValue);

	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_iload_2								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.4			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_lload_2()
{
	uint64_t tmpValue;

	tmpValue=JVM_Opcode_getLongVar(2);
	JVM_Opcode_pushLongValue(tmpValue);

	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_lload_3								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.4			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_lload_3()
{
	uint64_t tmpValue;

	tmpValue=JVM_Opcode_getLongVar(3);
	JVM_Opcode_pushLongValue(tmpValue);

	return(STCD_OK);
}



/********************************* Float *************************************************/




/****************************************************************************************/
/*																						*/
/*	Function : JVM_LoadConstant								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_LoadConstant(uint16_t index)

{

	JVM_StackFrame_t * myStackFrame;

	uint8_t constantType;


	myStackFrame=JVM_Opcode_getActiveStackFrame();

	constantType=JVM_CPTable_getCpType(myStackFrame->currentCpTable,index);

	JVM_CP_Integer_t * myCpIntegerInfo;
	JVM_CP_Float_t * myCpFloatInfo;
	JVM_CP_Long_t * myCpLongInfo;
	JVM_CP_Double_t * myCpDoubleInfo;


	union data_value value;


	switch (constantType)
	{
	case CONSTANT_TYPE_INTEGER:
		myCpIntegerInfo=JVM_CPTable_getIntegerInfo(myStackFrame->currentCpTable,index);
		value.intValue=myCpIntegerInfo->value;
		JVM_Opcode_pushIntValue(value.intValue);

		break;



	case CONSTANT_TYPE_FLOAT:
		myCpFloatInfo=JVM_CPTable_getFloatInfo(myStackFrame->currentCpTable,index);
		value.floatValue=myCpFloatInfo->value;
		JVM_Opcode_pushFloatValue(value.floatValue);
		break;


	case CONSTANT_TYPE_LONG:
		myCpLongInfo=JVM_CPTable_getLongInfo(myStackFrame->currentCpTable,index);
		// TODO Check !!!
		value.longValue=myCpLongInfo->value;
		JVM_Opcode_pushLongValue(value.longValue);

		break;



	case CONSTANT_TYPE_DOUBLE:
		myCpDoubleInfo=JVM_CPTable_getDoubleInfo(myStackFrame->currentCpTable,index);
		// TODO Check !!!
		value.doubleValue=myCpDoubleInfo->value;
		JVM_Opcode_pushDoubleValue(value.doubleValue);
		break;

	case CONSTANT_TYPE_STRING:
		createStringInstance(index);
		break;

	default:
		return(-1);
	}



	return(STCD_OK);
}

/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_ldc								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_ldc()
{
	uint8_t index;

	index=JVM_Opcode_getCodeByte();


	return(JVM_LoadConstant(index));
}
/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_ldc_w								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_ldc_w()
{
	uint16_t index;

	index=JVM_Opcode_getCodeShort();


	return(JVM_LoadConstant(index));
}


/****************************************************************************************/
/*																						*/
/*	Function : JVM_cmd_ldc2_w								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.5			Status : Working   			*/
/*																						*/
/****************************************************************************************/

uint16_t JVM_cmd_ldc2_w()
{
	uint16_t index;

	index=JVM_Opcode_getCodeShort();

	return(JVM_LoadConstant(index));



}




/****************************************************************************************/
/*																						*/
/*	Function : createStringInstance							Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.1.12			Status : Working   			*/
/*																						*/
/****************************************************************************************/

JVM_HandleNumber_t createStringInstance(uint16_t index)
{

	JVM_CP_String_t *myCpStringInfo;
	JVM_CP_UTF8_t *myCpUtf8Info;

	JVM_StackFrame_t * myStackFrame;

	myStackFrame = JVM_Opcode_getActiveStackFrame();

	myCpStringInfo=JVM_CPTable_getStringInfo(myStackFrame->currentCpTable,index);
	// TODO Check !!!
	myCpUtf8Info=JVM_CPTable_getUtf8Info(myStackFrame->currentCpTable,myCpStringInfo->stringIndex);
	// TODO Check !!!
//		myCpUtf8Info->


	JVM_HandleNumber_t  myInstance;


	myInstance=JVM_Handle_newInstance(JVM_ClassTable_get(JAVA_LANG_STRING_INDEX));


	//set Reference on Top of the Stack
	JVM_StackFrame_pushReference(myStackFrame,myInstance);

	uint16_t stringSize;

	stringSize=JVM_CP_Utf8_getStringSize(myCpUtf8Info);

	JVM_HandleNumber_t  myArray;


	// CREATE NEW String
	myArray=JVM_Handle_newArray(stringSize*2,0); //TODO Class Pointer

	JVM_Handle_arraySetLenght(myArray,stringSize);
	// new String
	// fill String

	//TODO find field !!!!!
	JVM_Handle_instanceSetReference(myInstance,JAVA_LANG_STRING_DATA_INDEX,myArray);


	uint16_t charArray[stringSize];
	uint16_t counter;

	JVM_CP_Utf8_copyString(myCpUtf8Info,(uint16_t*)&charArray);

	for (counter=0;counter<stringSize;counter++)
		{
		JVM_Handle_arraySetChar(myArray,counter,charArray[counter]);
		}



	return(STCD_OK);
}


